package org.sq;

import org.osmdroid.tileprovider.tilesource.ITileSource;
import org.osmdroid.tileprovider.tilesource.TileSourceFactory;
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.MapView;
import org.osmdroid.views.Projection;
import org.osmdroid.views.overlay.Overlay;
import org.osmdroid.views.overlay.OverlayManager;
import org.osmdroid.views.overlay.compass.CompassOverlay;
import org.osmdroid.views.overlay.compass.InternalCompassOrientationProvider;
import org.osmdroid.views.overlay.mylocation.GpsMyLocationProvider;
import org.osmdroid.views.overlay.mylocation.MyLocationNewOverlay;

import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Point;

public class NavigationFragment extends Fragment {

	private static final String PREFS_NAME = "SQ_PREFS";
	private static final long GPS_UPDATE_INTERVAL = 1; // 1-second interval.
	private static final float GPS_UPDATE_DISTANCE = 1;// 1 meters.
	LocationManager locationManager;
	private TextView latText;
	private TextView longText;
	private TextView targetLatText;
	private TextView targetLongText;
	private TextView bearingText;
	private TextView distanceText;
	private TextView accuracyText;
	private TextView titleText;
	private SQMapView mMapView;
	private MyLocationNewOverlay mLocationOverlay;
	private CompassOverlay mCompassOverlay;

	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		View view = inflater.inflate(R.layout.navigation, container, false);

		latText = (TextView) view.findViewById(R.id.latText);
		longText = (TextView) view.findViewById(R.id.longText);
		targetLatText = (TextView) view.findViewById(R.id.targetLatText);
		targetLongText = (TextView) view.findViewById(R.id.targetLongText);
		bearingText = (TextView) view.findViewById(R.id.targetBearingText);
		distanceText = (TextView) view.findViewById(R.id.targetDistText);
		accuracyText = (TextView) view.findViewById(R.id.accuracyText);
		titleText = (TextView) view.findViewById(R.id.title);
		mMapView = (SQMapView) view.findViewById(R.id.mapview);

		return view;
	}

	public void onActivityCreated(Bundle savedInstanceState)
    {
        super.onActivityCreated(savedInstanceState);

        final Context context = this.getActivity();
        this.mCompassOverlay = new CompassOverlay(context, new InternalCompassOrientationProvider(context),
                mMapView);
        this.mLocationOverlay = new MyLocationNewOverlay(context, new GpsMyLocationProvider(context),
                mMapView);


        mMapView.setBuiltInZoomControls(false);
        mMapView.setMultiTouchControls(true);
        mMapView.getOverlays().add(this.mLocationOverlay);
        mMapView.getOverlays().add(this.mCompassOverlay);
        final ITileSource tileSource = TileSourceFactory.CYCLEMAP;
        mMapView.setTileSource(tileSource);

        mMapView.getController().setZoom(mMapView.getMaxZoomLevel() - 2);

		mLocationOverlay.enableMyLocation();
		mLocationOverlay.enableFollowLocation();
		mCompassOverlay.enableCompass();
		
		MyOverlay myOverlay = new MyOverlay(context.getApplicationContext());
        appendOverlay(myOverlay);

    }

	public void onStart() {
		super.onStart();
		final LevelManager levelManager = ((SQApp) getActivity()
				.getApplicationContext()).levelManager();
		Log.d("Nav", "onStart");
		locationManager = (LocationManager) getActivity().getSystemService(
				Context.LOCATION_SERVICE);

		SharedPreferences settings = getActivity().getSharedPreferences(
				PREFS_NAME, 0);
		latText.setText(settings.getString("lat", "0"));
		longText.setText(settings.getString("lng", "0"));
		/*
		 * Location lastLocation = new Location(LocationManager.GPS_PROVIDER);
		 * try{ Double lat = Double.parseDouble(settings.getString("lat", "0"));
		 * Double lon = Double.parseDouble(settings.getString("lng", "0"));
		 * lastLocation.setLatitude(lat); lastLocation.setLongitude(lon); }
		 * catch(Exception ex){ Log.d("Nav", "Location parse error: " + ex); }
		 */
		titleText.setText(levelManager.getQuestTitle());
		targetLatText.setText(""
				+ levelManager.getQuestLocation().getLatitude());
		targetLongText.setText(""
				+ levelManager.getQuestLocation().getLongitude());
		if (locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER) != null) {

			makeUseOfNewLocation(locationManager
					.getLastKnownLocation(LocationManager.GPS_PROVIDER));
		}

		if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
			AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
			builder.setMessage(R.string.gps_alert_text)
					.setTitle(R.string.gps_info)
					.setPositiveButton(R.string.turn, GPSDialogClickListener)
					.setNegativeButton(R.string.cancel, GPSDialogClickListener)
					.show();
		} else {

			locationManager.requestLocationUpdates(
					LocationManager.GPS_PROVIDER, GPS_UPDATE_INTERVAL,
					GPS_UPDATE_DISTANCE, locationListener);
		}

	}

	// Define a listener that responds to location updates
	LocationListener locationListener = new LocationListener() {
		public void onLocationChanged(Location location) {
			// Called when a new location is found by the network location
			// provider.
			makeUseOfNewLocation(location);
		}

		public void onStatusChanged(String provider, int status, Bundle extras) {
		}

		public void onProviderEnabled(String provider) {
		}

		public void onProviderDisabled(String provider) {
		}
	};

	protected void makeUseOfNewLocation(Location location) {
		final LevelManager levelManager = ((SQApp) getActivity()
				.getApplicationContext()).levelManager();
		
		final GeoPoint l = new GeoPoint(location);
		mMapView.getController().setCenter(l);

		titleText.setText(levelManager.getQuestTitle());
		latText.setText("" + location.getLatitude());
		longText.setText("" + location.getLongitude());
		targetLatText.setText(""
				+ levelManager.getQuestLocation().getLatitude());
		targetLongText.setText(""
				+ levelManager.getQuestLocation().getLongitude());

		float bearing = location.bearingTo(levelManager.getQuestLocation());
		if (bearing < 0) {
			bearing = 360 + bearing;
		}
		bearingText.setText("" + (int) bearing + "°");
		float distance = location.distanceTo(levelManager.getQuestLocation());
		distanceText.setText("" + (int) distance + " м");
		accuracyText.setText(String.format("%.1f", location.getAccuracy())
				+ " м");

	}

	public void onResume() {
		super.onResume();
		final LevelManager levelManager = ((SQApp) getActivity()
				.getApplicationContext()).levelManager();

		Log.d("Nav", "onResume");
		titleText.setText(levelManager.getQuestTitle());
		targetLatText.setText(""
				+ levelManager.getQuestLocation().getLatitude());
		targetLongText.setText(""
				+ levelManager.getQuestLocation().getLongitude());
		if (locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER) != null) {
			makeUseOfNewLocation(locationManager
					.getLastKnownLocation(LocationManager.GPS_PROVIDER));
		}

	}

	public void onStop() {
		locationManager.removeUpdates(locationListener);
		SharedPreferences settings = getActivity().getSharedPreferences(
				PREFS_NAME, 0);
		SharedPreferences.Editor editor = settings.edit();
		editor.putString("lat", latText.getText().toString());
		editor.putString("lng", longText.getText().toString());
		editor.commit();
		super.onStop();
	}

	DialogInterface.OnClickListener GPSDialogClickListener = new DialogInterface.OnClickListener() {

		public void onClick(DialogInterface dialog, int which) {
			switch (which) {
			case DialogInterface.BUTTON_POSITIVE:
				startActivityForResult(
						new Intent(
								android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS),
						0);
				break;
			case DialogInterface.BUTTON_NEGATIVE:
				break;

			}

		}
	};

	protected void removerOverlay(Overlay overlay) {
		final OverlayManager mng = mMapView.getOverlayManager();

		if (mng.contains(overlay)) {
			mng.remove(overlay);
		}

	}

	protected void appendOverlay(Overlay overlay) {
		final OverlayManager mng = mMapView.getOverlayManager();

		if (!mng.contains(overlay)) {
			mng.add(overlay);
		}

	}

	public class MyOverlay extends Overlay {

		public MyOverlay(Context ctx) {
			super(ctx);
			// this.mapView = mapView;
			// TODO Auto-generated constructor stub
		}

		@Override
		protected void draw(Canvas canvas, MapView arg1, boolean arg2) {
			final LevelManager levelManager = ((SQApp) getActivity()
					.getApplicationContext()).levelManager();

			 int radius = 100; // in meters 
			    Projection projection = mMapView.getProjection(); 
			    Point p = new Point(); 
			    Location location = levelManager.getQuestLocation();
			    projection.toPixels(new GeoPoint(location.getLatitude(), location.getLongitude()), p); 
			    float actualRadius = projection.metersToEquatorPixels(radius); 
			    Paint paint = new Paint(); 
			    paint.setColor(Color.BLUE); 
			    paint.setStyle(Style.STROKE);
			    paint.setAntiAlias(true);
			    paint.setStrokeWidth(2); 
			    canvas.drawCircle(p.x, p.y, actualRadius, paint); 
		}

	}

}
